package com.lse_from.config

import com.baomidou.mybatisplus.annotation.DbType
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean
import com.github.pagehelper.PageHelper
import com.zaxxer.hikari.HikariDataSource
import org.mybatis.spring.annotation.MapperScan
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.core.io.DefaultResourceLoader
import org.springframework.jdbc.datasource.DataSourceTransactionManager
import org.springframework.transaction.PlatformTransactionManager
import java.util.*
import javax.sql.DataSource

/**
 * mybatis plus 配置
 *
 * @author 祁雪
 */
@Configuration
@MapperScan(basePackages = ["com.*.mapper"])
class MybatisPlusConfig {

    @Value("\${spring.datasource.driver-class-name}")
    private val jdbcDriver: String? = null

    @Value("\${spring.datasource.url}")
    private val jdbcUrl: String? = null

    @Value("\${spring.datasource.username}")
    private val jdbcUsername: String? = null

    @Value("\${spring.datasource.password}")
    private val jdbcPassword: String? = null

    @Value("\${mybatis-plus.mapper-locations}")
    private val xmlPath: String? = null

    @Value("\${spring.datasource.hikari.minimum-idle}")
    private val minIdle: Int? = null

    @Value("\${spring.datasource.hikari.idle-timeout}")
    private val timeOut: Int? = null

    @Value("\${spring.datasource.hikari.maximum-pool-size}")
    private val maxPoolSize: Int? = null

    @Value("\${spring.datasource.hikari.auto-commit}")
    private val autoCommit: Boolean? = null

    @Value("\${spring.datasource.hikari.pool-name}")
    private val poolName: String? = null

    @Value("\${spring.datasource.hikari.max-lifetime}")
    private val maxLifeTime: Long? = null

    @Value("\${spring.datasource.hikari.connection-timeout}")
    private val connectionTimeout: Long? = null

    @Value("\${spring.datasource.hikari.connection-test-query}")
    private val connectionQuery: String? = null

    /**
     * 设置分页
     *
     * @return
     */
    @Bean
    fun pageHelper(): PageHelper? {
        val pageHelper = PageHelper()
        val p = Properties()
        p.setProperty("offsetAsPageNum", "true")
        p.setProperty("rowBoundsWithCount", "true")
        p.setProperty("reasonable", "true")
        pageHelper.setProperties(p)
        return pageHelper
    }

    /**
     * 数据源
     */
    @Bean
    fun dataSource(): DataSource? {
        val dataSource: HikariDataSource = object : HikariDataSource() {
            init {
                username = jdbcUsername
                jdbcUrl = jdbcUrl
                driverClassName = jdbcDriver
                password = jdbcPassword
            }
        }
        dataSource.username = jdbcUsername
        dataSource.jdbcUrl = jdbcUrl
        dataSource.driverClassName = jdbcDriver
        dataSource.password = jdbcPassword
        setDataSourceParams(dataSource)
        return dataSource
    }

    /**
     * 配置mp
     */
    //    @Bean
    fun mybatisPlusSqlSessionFactory(): MybatisSqlSessionFactoryBean? {
        val mybatisPlus = MybatisSqlSessionFactoryBean()
        mybatisPlus.setDataSource(dataSource())
        mybatisPlus.vfs = SpringBootVFS::class.java
        mybatisPlus.setMapperLocations(
            *arrayOf(
                DefaultResourceLoader().getResource(xmlPath!!)
            )
        )
        return mybatisPlus
    }

    @Bean
    fun paginationInterceptor(): MybatisPlusInterceptor? {
        val page = MybatisPlusInterceptor()
        //设置方言类型
        page.addInnerInterceptor(PaginationInnerInterceptor(DbType.POSTGRE_SQL))
        return page
    }

    /**
     * 配置@Transactional注解事物
     *
     * @return
     */
    @Bean
    fun transactionManager(): PlatformTransactionManager? {
        return DataSourceTransactionManager(dataSource()!!)
    }

    /**
     * 设置数据源公共参数
     *
     * @param dataSourceParams
     */
    fun setDataSourceParams(dataSourceParams: HikariDataSource) {
        dataSourceParams.minimumIdle = minIdle!!
        dataSourceParams.idleTimeout = timeOut!!.toLong()
        dataSourceParams.maximumPoolSize = maxPoolSize!!
        dataSourceParams.maxLifetime = maxLifeTime!!
        dataSourceParams.isAutoCommit = autoCommit!!
        dataSourceParams.poolName = poolName
        dataSourceParams.connectionTimeout = connectionTimeout!!
        dataSourceParams.connectionTestQuery = connectionQuery
    }

}